﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Clueless
{
    /// <summary>
    /// This shit is just for the testing UI...  
    /// </summary>
    public partial class Form1 : Form
    {
        Game currentGame;
        public Form1()
        {
            InitializeComponent();

            currentGame = new Game(this);
            currentGame.Start();
        }

        // Delgates...   Need these to cross threads
        public delegate void RoomDelegate(Room r);
        public delegate void StringDelegate(String s);
        public delegate void VoidDelegate();
        public delegate void PlayerListDelegate(PlayerList p);
        public delegate void CardDeckDelegate(CardDeck d);
        public delegate void PlayerDelegate(Player p);
        public delegate void BooleanDelegate(bool b);


        public void Output(String s)
        {
            if (outputBox.InvokeRequired)
                outputBox.Invoke(new StringDelegate(this.Output), s);
            else
                //outputBox.AppendText(s + "\n");
                outputBox.Text = outputBox.Text.Insert(0, s + "\n");
        }


        /************************* Cards *******************************/
        public void CardOutput(String s)
        {
            if (cardListBox.InvokeRequired)
                cardListBox.Invoke(new StringDelegate(this.CardOutput), s);
            else
                cardListBox.AppendText(s + "\n");

        }

        public void ResetCardOutput()
        {
            if (cardListBox.InvokeRequired)
                cardListBox.Invoke(new VoidDelegate(this.ResetCardOutput));
            else
                cardListBox.ResetText();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            currentGame.Reshuffle();
        }



        /************************* ROOMS *******************************/

        public void ResetNeighborListOutput()
        {
            if (neighborList.InvokeRequired)
                neighborList.Invoke(new VoidDelegate(this.ResetNeighborListOutput));
            else
                neighborList.Items.Clear();
        }

        public void NeighborOutput(Room r)
        {
            if (neighborList.InvokeRequired)
                neighborList.Invoke(new RoomDelegate(this.NeighborOutput), r);
            else
            {
                foreach (Room neighbor in r.NeighboringRooms)
                {
                    neighborList.Items.Add(neighbor.Name);
                }
            }
        }

        public void RoomOutput(Room r)
        {
            if (roomBox.InvokeRequired)
                roomBox.Invoke(new RoomDelegate(this.RoomOutput), r);
            else
            {
                roomBox.Text = r.Name;
            }
        }


        public void setRoom(Room r)
        {
            ResetNeighborListOutput();
            NeighborOutput(r);
            RoomOutput(r);
        }


        /// <summary>
        /// Triggered when clicking on an item in the neighbor list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void neighborList_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Output(neighborList.Text);
            if (neighborList.Text != "")
                setRoom(currentGame.Board.GetRoom(neighborList.Text));
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            currentGame.End();
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }


        

        /*********************************************************/
        /*********************************************************/
        /*********************************************************/
        /*******************      Board      *********************/
        /*********************************************************/
        /*********************************************************/
        public void AddToRoom(Player player)
        {
            switch (player.CurrentRoom.Name)
            {
                case "Study":
                    studyControl.AddPlayer(player.PlayerColor);
                    break;
                case "Study To Hall":
                    studyHallHall.AddPlayer(player.PlayerColor);
                    break;
                case "Hall":
                    hallControl.AddPlayer(player.PlayerColor);
                    break;
                case "Hall To Lounge":
                    hallLoungeHall.AddPlayer(player.PlayerColor);
                    break;
                case "Lounge":
                    loungeControl.AddPlayer(player.PlayerColor);
                    break;
                case "Lounge To Dining Room":
                    loungeDiningHall.AddPlayer(player.PlayerColor);
                    break;
                case "Dining Room":
                    diningHallControl.AddPlayer(player.PlayerColor);
                    break;
                case "Dining Room To Kitchen":
                    diningKitchenHall.AddPlayer(player.PlayerColor);
                    break;
                case "Kitchen":
                    kitchenControl.AddPlayer(player.PlayerColor);
                    break;
                case "Kitchen To Ballroom":
                    ballroomKitchenHall.AddPlayer(player.PlayerColor);
                    break;
                case "Ballroom":
                    ballroomControl.AddPlayer(player.PlayerColor);
                    break;
                case "Ballroom To Conservatory":
                    conservatoryBallroomHall.AddPlayer(player.PlayerColor);
                    break;
                case "Conservatory":
                    conservatoryControl.AddPlayer(player.PlayerColor);
                    break;
                case "Conservatory To Library":
                    libraryConservatoryHall.AddPlayer(player.PlayerColor);
                    break;
                case "Library":
                    libraryControl.AddPlayer(player.PlayerColor);
                    break;
                case "Library To Study":
                    studyLibraryHall.AddPlayer(player.PlayerColor);
                    break;
                case "Billard Room":
                    billiardRoomControl.AddPlayer(player.PlayerColor);
                    break;
                case "Library To Billard Room":
                    libraryBilliardHall.AddPlayer(player.PlayerColor);
                    break;
                case "Hall To Billard Room":
                    hallBilliardHall.AddPlayer(player.PlayerColor);
                    break;
                case "Dining Room To Billard Room":
                    billiardDiningHall.AddPlayer(player.PlayerColor);
                    break;
                case "Ballroom To Billard Room":
                    billiardBallroomHall.AddPlayer(player.PlayerColor);
                    break;
                default:
                    throw new Exception("WHAT THE FUCK DID YOU DO!?!?! - AddtoRoom: " + player.CurrentRoom.Name);
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void ClearAllHighlights()
        {
            if (studyControl.InvokeRequired)
                studyControl.Invoke(new VoidDelegate(ClearAllHighlights));
            else
            {
                studyControl.RemoveHighlight();
                studyHallHall.RemoveHighlight();
                hallControl.RemoveHighlight();
                hallLoungeHall.RemoveHighlight();
                loungeControl.RemoveHighlight();
                loungeDiningHall.RemoveHighlight();
                diningHallControl.RemoveHighlight();
                diningKitchenHall.RemoveHighlight();
                kitchenControl.RemoveHighlight();
                ballroomKitchenHall.RemoveHighlight();
                ballroomControl.RemoveHighlight();
                conservatoryBallroomHall.RemoveHighlight();
                conservatoryControl.RemoveHighlight();
                libraryConservatoryHall.RemoveHighlight();
                libraryControl.RemoveHighlight();
                studyLibraryHall.RemoveHighlight();
                billiardRoomControl.RemoveHighlight();
                libraryBilliardHall.RemoveHighlight();
                hallBilliardHall.RemoveHighlight();
                billiardDiningHall.RemoveHighlight();
                billiardBallroomHall.RemoveHighlight();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="r"></param>
        public void HighlightRoom(Room r)
        {
            switch (r.Name)
            {
                case "Study":
                    studyControl.SetHighlight();
                    break;
                case "Study To Hall":
                    studyHallHall.SetHighlight();
                    break;
                case "Hall":
                    hallControl.SetHighlight();
                    break;
                case "Hall To Lounge":
                    hallLoungeHall.SetHighlight();
                    break;
                case "Lounge":
                    loungeControl.SetHighlight();
                    break;
                case "Lounge To Dining Room":
                    loungeDiningHall.SetHighlight();
                    break;
                case "Dining Room":
                    diningHallControl.SetHighlight();
                    break;
                case "Dining Room To Kitchen":
                    diningKitchenHall.SetHighlight();
                    break;
                case "Kitchen":
                    kitchenControl.SetHighlight();
                    break;
                case "Kitchen To Ballroom":
                    ballroomKitchenHall.SetHighlight();
                    break;
                case "Ballroom":
                    ballroomControl.SetHighlight();
                    break;
                case "Ballroom To Conservatory":
                    conservatoryBallroomHall.SetHighlight();
                    break;
                case "Conservatory":
                    conservatoryControl.SetHighlight();
                    break;
                case "Conservatory To Library":
                    libraryConservatoryHall.SetHighlight();
                    break;
                case "Library":
                    libraryControl.SetHighlight();
                    break;
                case "Library To Study":
                    studyLibraryHall.SetHighlight();
                    break;
                case "Billard Room":
                    billiardRoomControl.SetHighlight();
                    break;
                case "Library To Billard Room":
                    libraryBilliardHall.SetHighlight();
                    break;
                case "Hall To Billard Room":
                    hallBilliardHall.SetHighlight();
                    break;
                case "Dining Room To Billard Room":
                    billiardDiningHall.SetHighlight();
                    break;
                case "Ballroom To Billard Room":
                    billiardBallroomHall.SetHighlight();
                    break;
                default:
                    throw new Exception("WHAT THE FUCK DID YOU DO!?!?! - Highlightroom: " + r.Name);
                    break;
            }
        }

        public void ClearAllRooms()
        {
            if (studyControl.InvokeRequired)
                studyControl.Invoke(new VoidDelegate(ClearAllRooms));
            else
            {
                studyControl.RemovePlayer();
                studyHallHall.RemovePlayer();
                hallControl.RemovePlayer();
                hallLoungeHall.RemovePlayer();
                loungeControl.RemovePlayer();
                loungeDiningHall.RemovePlayer();
                diningHallControl.RemovePlayer();
                diningKitchenHall.RemovePlayer();
                kitchenControl.RemovePlayer();
                ballroomKitchenHall.RemovePlayer();
                ballroomControl.RemovePlayer();
                conservatoryBallroomHall.RemovePlayer();
                conservatoryControl.RemovePlayer();
                libraryConservatoryHall.RemovePlayer();
                libraryControl.RemovePlayer();
                studyLibraryHall.RemovePlayer();
                billiardRoomControl.RemovePlayer();
                libraryBilliardHall.RemovePlayer();
                hallBilliardHall.RemovePlayer();
                billiardDiningHall.RemovePlayer();
                billiardBallroomHall.RemovePlayer();
            }
        }

        private void RequestMovement(String roomName)
        {
            Console.WriteLine("RequestMovement");
            currentGame.AttemptMove(roomName);
        }


        /// <summary>
        /// I hate myself for the next group of lines!
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void studyControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Study");
            
        }

        private void studyHallHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Study To Hall");
        }

        private void hallControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Hall");
        }

        private void hallLoungeHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Hall To Lounge");
        }

        private void loungeControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Lounge");
        }

        private void loungeDiningHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Lounge To Dining Room");
        }

        private void diningHallControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Dining Room");
        }

        private void diningKitchenHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Dining Room To Kitchen");
        }

        private void kitchenControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Kitchen");
        }

        private void ballroomKitchenHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Kitchen To Ballroom");
        }

        private void ballroomControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Ballroom");
        }

        private void conservatoryBallroomHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Ballroom To Conservatory");
        }

        private void conservatoryControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Conservatory");
        }

        private void libraryConservatoryHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Conservatory To Library");
        }

        private void libraryControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Library");
        }

        private void studyLibraryHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Library To Study");
        }

        private void libraryBilliardHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Library To Billard Room");
        }

        private void hallBilliardHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Hall To Billard Room");
        }

        private void billiardDiningHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Dining Room To Billard Room");
        }

        private void billiardBallroomHall_Click(object sender, EventArgs e)
        {
            RequestMovement("Ballroom To Billard Room");
        }

        private void billiardRoomControl_Click(object sender, EventArgs e)
        {
            RequestMovement("Billard Room");
        }

        private void studyControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Study");
        }

        private void studyHallHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Study To Hall");
        }

        private void hallControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Hall");
        }

        private void hallLoungeHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Hall To Lounge");
        }

        private void loungeControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Lounge");
        }

        private void loungeDiningHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Lounge To Dining Room");
        }

        private void diningHallControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Dining Room");
        }

        private void diningKitchenHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Dining Room To Kitchen");
        }

        private void kitchenControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Kitchen");
        }

        private void ballroomKitchenHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Kitchen To Ballroom");
        }

        private void ballroomControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Ballroom");
        }

        private void conservatoryBallroomHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Ballroom To Conservatory");
        }

        private void conservatoryControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Conservatory");
        }

        private void libraryConservatoryHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Conservatory To Library");
        }

        private void libraryControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Library");
        }

        private void studyLibraryHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Library To Study");
        }

        private void libraryBilliardHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Library To Billard Room");
        }

        private void hallBilliardHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Hall To Billard Room");
        }

        private void billiardDiningHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Dining Room To Billard Room");
        }

        private void billiardBallroomHall_MovementClick(object sender, HallControl.MovementClickEventArgs e)
        {
            RequestMovement("Ballroom To Billard Room");
        }

        private void billiardRoomControl_MovementClick(object sender, RoomControl.MovementClickEventArgs e)
        {
            RequestMovement("Billard Room");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="players"></param>
        public void ListPlayers(PlayerList players)
        {

            if (lstPlayers.InvokeRequired)
                lstPlayers.Invoke(new PlayerListDelegate(this.ListPlayers), players);
            else
            {
                lstPlayers.Items.Clear();

                foreach (Player p in players.Players)
                {
                    if (p.Character.Name == players.GetCurrentPlayer().Character.Name)
                    {
                        lstPlayers.Items.Add(p.Character.Name + " **");
                    }
                    else if (!p.Active)
                    {
                        lstPlayers.Items.Add(p.Character.Name + " OUT");
                    }
                    else
                    {
                        lstPlayers.Items.Add(p.Character.Name);
                    }
                }
            }
        }

        public void SetSuggestButtonVisibility(bool show)
        {
            if (btnSuggest.InvokeRequired)
                btnSuggest.Invoke(new BooleanDelegate(SetSuggestButtonVisibility), show);
            else
            {
                btnSuggest.Visible = show;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="deck"></param>
        public void ListCards(CardDeck deck)
        {
            if (lstCards.InvokeRequired)
                lstCards.Invoke(new CardDeckDelegate(this.ListCards), deck);
            else
            {
                lstCards.Items.Clear();

                foreach (Card c in deck.Cards)
                {
                    lstCards.Items.Add(c.Name);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        public void SetPlayerName(Player p)
        {
            if (activeTitleBar.InvokeRequired)
                activeTitleBar.Invoke(new PlayerDelegate(SetPlayerName), p);
            else
            {
                activeTitleBar.Text = p.Character.Name;
            }
            
        }

        public void SetTurn(bool myturn)
        {
            /*if (button2.InvokeRequired)
                button2.Invoke(new BooleanDelegate(SetTurn), myturn);
            else
            {
                button2.Enabled = myturn;
            }*/
        }

        private void button2_Click(object sender, EventArgs e)
        {
            currentGame.EndTurn();
        }

        private void btnAccuse_Click(object sender, EventArgs e)
        {
            // TODO
            currentGame.OpenAccusation();
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        internal void EnableAccuse(bool p)
        {
            if (btnAccuse.InvokeRequired)
                btnAccuse.Invoke(new BooleanDelegate(EnableAccuse), p);
            else
            {
                btnAccuse.Enabled = p;
            }
        }

        private void playButton_Click(object sender, EventArgs e)
        {
            JoinHost frmJoinHost = new JoinHost();
            frmJoinHost.SetValues("192.168.2.2", "1000");
            frmJoinHost.Show();
            frmJoinHost.AttemptJoin += AttemptJoin;
        }

        private void AttemptJoin(object sender, JoinEventArgs e)
        {
            tabControl1.SelectedTab = tabControl1.TabPages[1];
            currentGame.StartNetwork(e.IP, e.Port);
        }

        private void exitButton_Click(object sender, EventArgs e)
        {

        }

        private void btnSuggest_Click(object sender, EventArgs e)
        {
            
            currentGame.OpenSuggestion();
        }
    }
}
